package com.morristaedt.mirror.modules.voice;

import android.app.Activity;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.VoiceWakeuper;
import com.iflytek.cloud.WakeuperListener;
import com.iflytek.cloud.util.ResourceUtil;
import com.morristaedt.mirror.R;

/**
 * 语音唤醒模块
 *
 */
public class VoiceModule  {

    private static final String TAG = "VoiceModule";
    private Activity context;
    // 语音唤醒对象
    private VoiceWakeuper mIvw;
    // 语音听写对象
    private SpeechRecognizer mIat;
    private final static int MAX = 60;
    private final static int MIN = -20;
    private int curThresh = 10;
    private String keep_alive = "1";
    /**
     * 闭环优化网络模式有三种：
     * 模式0：关闭闭环优化功能
     *
     * 模式1：开启闭环优化功能，允许上传优化数据。需开发者自行管理优化资源。
     * sdk提供相应的查询和下载接口，请开发者参考API文档，具体使用请参考本示例
     * queryResource及downloadResource方法；
     *
     * 模式2：开启闭环优化功能，允许上传优化数据及启动唤醒时进行资源查询下载；
     * 本示例为方便开发者使用仅展示模式0和模式2；
     */
    private String ivwNetMode = "0";
    private WakeuperListener mWakeuperListener;
    /**
     * 听写监听器。
     */
    private RecognizerListener mRecognizerListener;
    /**
     * 初始化监听器。
     */
    private InitListener mInitListener = new InitListener() {

        @Override
        public void onInit(int code) {
            Log.d(TAG, "SpeechRecognizer init() code = " + code);
            if (code != ErrorCode.SUCCESS) {
                showTip("初始化失败，错误码：" + code);
            }
        }
    };

//    public VoiceModule(Activity context, WakeuperListener listener,RecognizerListener mRecognizerListener) {
//        this.context = context;
//        this.mWakeuperListener=listener;
//        this.mRecognizerListener = mRecognizerListener;
//        // 初始化唤醒对象
//        mIvw = VoiceWakeuper.createWakeuper(context, null);
//        // 使用SpeechRecognizer对象，可根据回调消息自定义界面；
//        mIat = SpeechRecognizer.createRecognizer(context, mInitListener);
//    }

    public VoiceModule(Activity context, WakeuperListener listener) {
        this.context = context;
        this.mWakeuperListener=listener;
        // 初始化唤醒对象
        mIvw = VoiceWakeuper.createWakeuper(context, mInitListener);
        // 使用SpeechRecognizer对象，可根据回调消息自定义界面；
//        mIat = SpeechRecognizer.createRecognizer(context, mInitListener);

    }



    public void startWake(){
        //非空判断，防止因空指针使程序崩溃
        mIvw = VoiceWakeuper.getWakeuper();
        if (mIvw == null){
            mIvw = VoiceWakeuper.createWakeuper(context, mInitListener);
        }
        if(mIvw != null) {

            // 清空参数
            mIvw.setParameter(SpeechConstant.PARAMS, null);
            // 唤醒门限值，根据资源携带的唤醒词个数按照“id:门限;id:门限”的格式传入
            mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:"+ curThresh);
            // 设置唤醒模式
            mIvw.setParameter(SpeechConstant.IVW_SST, "wakeup");
            // 设置持续进行唤醒
            mIvw.setParameter(SpeechConstant.KEEP_ALIVE, keep_alive);
            // 设置闭环优化网络模式
            mIvw.setParameter(SpeechConstant.IVW_NET_MODE, ivwNetMode);
            // 设置唤醒资源路径
            mIvw.setParameter(SpeechConstant.IVW_RES_PATH, getResource());
            // 设置唤醒录音保存路径，保存最近一分钟的音频
            mIvw.setParameter( SpeechConstant.IVW_AUDIO_PATH, Environment.getExternalStorageDirectory().getPath()+"/msc/ivw.wav" );
            mIvw.setParameter( SpeechConstant.AUDIO_FORMAT, "wav" );
            // 如有需要，设置 NOTIFY_RECORD_DATA 以实时通过 onEvent 返回录音音频流字节
            //mIvw.setParameter( SpeechConstant.NOTIFY_RECORD_DATA, "1" );

            // 启动唤醒
            mIvw.startListening(mWakeuperListener);
        } else {
            showTip("唤醒未初始化");
        }

//        if(mIat != null){
//            mIat.setParameter(SpeechConstant.PARAMS, null);
//            // 设置语言
//            mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
//            // 设置语言区域
//            mIat.setParameter(SpeechConstant.ACCENT,"mandarin");
//            // 设置引擎
//            mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
//            // 设置返回结果格式
//            mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
//
//            // 设置语音前端点:静音超时时间，即用户多长时间不说话则当做超时处理
//            mIat.setParameter(SpeechConstant.VAD_BOS,  "4000");
//
//            // 设置语音后端点:后端点静音检测时间，即用户停止说话多长时间内即认为不再输入， 自动停止录音
//            mIat.setParameter(SpeechConstant.VAD_EOS,  "3000");
//
//            // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
//            mIat.setParameter(SpeechConstant.ASR_PTT,  "1");
//
//            // 设置音频保存路径，保存音频格式支持pcm、wav，设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
//            mIat.setParameter(SpeechConstant.AUDIO_FORMAT,"wav");
//            mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/iat.wav");
//        }else {
//            showTip("语音识别未初始化");
//        }

    }

    public boolean isListening(){
        return mIvw !=null && mIvw.isListening();
    }

    public void startSpeech(){
        int ret = mIat.startListening(mRecognizerListener);
        if (ret != ErrorCode.SUCCESS) {
            showTip("听写失败,错误码：" + ret);
        } else {
            showTip("请开始说话...");
        }
    }

    public void stopWake(){
        if (mIvw != null){
            mIvw.stopListening();
        }
        if (mIat != null){
            mIat.cancel();
        }

    }

    public void releaseWake(){
        Log.d(TAG, "onDestroy WakeDemo");
        // 销毁合成对象
        mIvw = VoiceWakeuper.getWakeuper();
        if (mIvw != null) {
            mIvw.destroy();
        }
    }

    public void releaseSpeech(){
        if( null != mIat ){
            // 退出时释放连接
            mIat.cancel();
            mIat.destroy();
        }
    }

    public void destroy(){
        releaseWake();
       releaseSpeech();
    }



    private String getResource() {
        return ResourceUtil.generateResourcePath(context, ResourceUtil.RESOURCE_TYPE.assets, "ivw/"+context.getString(R.string.app_id)+".jet");
    }

    private void showTip(final String str) {
        context.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
            }
        });
    }
}
